package indi.zhifa.learn.jenkins.helloworld2.web.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import indi.zhifa.learn.jenkins.helloworld2.common.entity.ServiceException;
import indi.zhifa.learn.jenkins.helloworld2.web.dao.service.IAnalysisTaskDaoService;
import indi.zhifa.learn.jenkins.helloworld2.web.entity.dto.DataAnalysisResult;
import indi.zhifa.learn.jenkins.helloworld2.web.entity.enums.EAnalysisStatus;
import indi.zhifa.learn.jenkins.helloworld2.web.entity.po.AnalysisTask;
import indi.zhifa.learn.jenkins.helloworld2.web.entity.request.DocKeyPassConfig;
import indi.zhifa.learn.jenkins.helloworld2.web.service.IDocAnalysisService;
import indi.zhifa.learn.jenkins.helloworld2.web.service.algorithm.PdfDocument;
import indi.zhifa.learn.jenkins.helloworld2.web.service.algorithm.datastructure.DocResultSet;
import indi.zhifa.learn.jenkins.helloworld2.web.service.algorithm.datastructure.DocValueResult;
import indi.zhifa.learn.jenkins.helloworld2.web.service.algorithm.datastructure.PassResultItem;
import indi.zhifa.learn.jenkins.helloworld2.web.util.IMinioUtil;
import io.minio.GetObjectResponse;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.pdfbox.Loader;
import org.apache.pdfbox.pdmodel.*;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.util.*;

@AllArgsConstructor
@Service
@Slf4j
public class DocAnalysisServiceImpl implements IDocAnalysisService {

    private final IAnalysisTaskDaoService mAnalysisTaskDaoService;
    private final IMinioUtil mMinioUtil;

    @Override
    public DocResultSet analysis(PDDocument pDoc, DocKeyPassConfig pDocKeyPassConfig) throws Exception {
        PdfDocument pdfDocument = new PdfDocument(pDocKeyPassConfig);
        pdfDocument.handlePdfSimple(pDoc);
        return pdfDocument.getDocResultSet();
    }

    @Override
    public AnalysisTask create(Long pUserId, DocKeyPassConfig pKeyConfig) {
        AnalysisTask analysisTask = new AnalysisTask();
        analysisTask.createInit();
        analysisTask.setResult(null);
        if(null == pKeyConfig){
            pKeyConfig = new DocKeyPassConfig();
        }
        analysisTask.setUserId(pUserId);
        analysisTask.setStatus(EAnalysisStatus.EMPTY);
        analysisTask.setFilePath(null);
        analysisTask.setKeyConfig( pKeyConfig);
        DocResultSet docResultSet = new DocResultSet();
        analysisTask.setResult(docResultSet);
        mAnalysisTaskDaoService.save(analysisTask);
        return analysisTask;
    }

    @Override
    public AnalysisTask uploadFile(Long pTaskId, MultipartFile pFile) {
        AnalysisTask analysisTask = checkAnalysisTask(pTaskId);
        try{
            String filePath = mMinioUtil.putFile(CollectionUtil.newArrayList("pdf_"+pTaskId),pFile);
            analysisTask.setFilePath(filePath);
            DocKeyPassConfig keyConfig = analysisTask.getKeyConfig();
            if(null != keyConfig){
                analysisTask.setStatus(EAnalysisStatus.UPLOAD);
            }
            mAnalysisTaskDaoService.updateById(analysisTask);
            return analysisTask;
        }catch (Exception ex){
            throw new ServiceException("上传文件时发生错误，错误信息是"+ex.toString());
        }
    }

    @Override
    public AnalysisTask editKeyConfig(Long pTaskId, DocKeyPassConfig pKeyConfig) {
        AnalysisTask analysisTask = checkAnalysisTask(pTaskId);
        analysisTask.setKeyConfig(pKeyConfig);
        String filePath = analysisTask.getFilePath();
        if(StringUtils.hasLength(filePath)){
            analysisTask.setStatus(EAnalysisStatus.UPLOAD);
        }
        mAnalysisTaskDaoService.updateById(analysisTask);
        return analysisTask;
    }

    @Override
    public AnalysisTask analysis(Long pTaskId){
        AnalysisTask analysisTask = checkAnalysisTask(pTaskId);
        String filePath = analysisTask.getFilePath();

        try{
            GetObjectResponse minIoResponse = mMinioUtil.getFile(filePath);
            PDDocument document = Loader.loadPDF(minIoResponse);
            DocKeyPassConfig docKeyPassConfig = analysisTask.getKeyConfig();
            PdfDocument pdfDocument = new PdfDocument(docKeyPassConfig);
            pdfDocument.handlePdfSimple(document);
            DocResultSet result = pdfDocument.getDocResultSet();
            analysisTask.setResult(result);
            boolean success = true;
            for(PassResultItem docValueResult : result.getPassResults()){
                if(!docValueResult.isSuccess()){
                    success = false;
                    analysisTask.setErrorInfo(docValueResult.getErrInfo());
                    break;
                }
            }
            if(success){
                analysisTask.setStatus(EAnalysisStatus.FINISH);
                analysisTask.setErrorInfo(null);
            }else{
                analysisTask.setStatus(EAnalysisStatus.ERROR);
            }
            mAnalysisTaskDaoService.updateById(analysisTask);
            return analysisTask;
        }catch (Exception ex){
            analysisTask.setStatus(EAnalysisStatus.ERROR);
            analysisTask.setErrorInfo(ex.toString());
            mAnalysisTaskDaoService.updateById(analysisTask);
        }
        return analysisTask;
    }

    @Override
    public AnalysisTask info(Long pTaskId) {
        return checkAnalysisTask(pTaskId);
    }

    @Override
    public List<AnalysisTask> list(Long pUserId) {
        return mAnalysisTaskDaoService.listByUserId(pUserId);
    }

    @Override
    public void deleteTask(Long pTaskId) {
        AnalysisTask analysisTask = checkAnalysisTask(pTaskId);
        mAnalysisTaskDaoService.removeById(pTaskId);
    }

    protected AnalysisTask checkAnalysisTask(Long pTaskId){
        AnalysisTask analysisTask = mAnalysisTaskDaoService.getById(pTaskId);
        if(null == analysisTask){
            throw new ServiceException("没有找到Id为"+pTaskId+"分析任务Id");
        }
        return analysisTask;
    }

}
